﻿using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TaskParallelProgramming
{
    public static class Busy
    {
        private static BusyIndicatorForm busy;

        private class BusyIndicatorForm : Form
        {
            public bool TimedOut { get; set; }

            public BusyIndicatorForm()
            {
                var progressBar = new ProgressBar();
                progressBar.Dock = DockStyle.Fill;
                progressBar.Style = ProgressBarStyle.Marquee;
                Controls.Add(progressBar);

                AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
                AutoScaleMode = AutoScaleMode.Font;
                ClientSize = new System.Drawing.Size(180, 35);
                ControlBox = false;
                FormBorderStyle = FormBorderStyle.FixedToolWindow;
                MaximizeBox = false;
                MinimizeBox = false;
                Name = "BusyIndicatorForm";
                ShowIcon = false;
                ShowInTaskbar = false;
                StartPosition = FormStartPosition.CenterParent;
                Text = "Working..."; ;
            }
        }

        public static bool Show(IWin32Window window)
        {
            busy = new BusyIndicatorForm();
            busy.Shown += (o, e) => Task.Delay(5000).ContinueWith(x => Hide(true));
            busy.ShowDialog(window);

            if (!busy.TimedOut)
            {
                MessageBox.Show(window, "Respond", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                MessageBox.Show(window, "Timed Out", "Fail", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            return busy.TimedOut;
        }
        private static void Hide(bool timedOut)
        {
            if (busy != null)
            {
                busy.TimedOut = timedOut;
                busy.InvokeOrExecute(() => busy.Close());
            }
        }
        public static void Hide()
        {
            Hide(false);
        }
    }

    public static class ControlExtensions
    {
        public static void InvokeOrExecute(this Control control, Action action)
        {
            if (control.InvokeRequired)
                control.Invoke(action);
            else action.Invoke();
        }
    }
}